<template>
  <div class="table-box">
    <Table ref="tableRef" row-key="id" :columns="columns" :request-api="microAppApi.list">
      <template #header>
        <ElButton type="primary" icon="CirclePlus" @click="handleAdd">新增应用</ElButton>
      </template>
      <!-- 菜单操作 -->
      <template #action="{ row, id }">
        <TableAction :actions="getActions(row, id)" :show-num="0"></TableAction>
      </template>
    </Table>
    <Drawer ref="drawerRef" @submit="handleSubmit" :title="title" size="50%" @open="openWatch">
      <ElCard>
        <template #header>基础信息</template>
        <Form ref="basicFormRef" :schemas="basicSchemas" label-width="80px">
          <template #entityId="{ formModel, schema }">
            <Select v-model="formModel[schema.field]" :options="entityList" label-name="entityName" value-name="id"></Select>
          </template>
        </Form>
      </ElCard>
      <br />
      <ElCard>
        <template #header>实体模型</template>
        <ElTable :data="modelList">
          <ElTableColumn prop="joinEntityId" label="关联实体">
            <template #default="{ row }">
              <Select
                v-model="row['joinEntityId']"
                :options="entityList"
                label-name="entityName"
                value-name="id"
                @change="handleEntityModelChange"
              ></Select>
            </template>
          </ElTableColumn>
          <ElTableColumn prop="joinEntityField" label="关联字段">
            <template #default="{ row }">
              <Select
                v-model="row['joinEntityField']"
                :options="joinTableColumnMap[row['joinEntityId']]"
                label-name="fieldName"
                value-name="fieldCode"
              >
              </Select>
            </template>
          </ElTableColumn>
          <ElTableColumn prop="entityField" label="实体字段">
            <template #default="{ row }">
              <Select v-model="row['entityField']" :options="fieldList" label-name="fieldName" value-name="fieldCode"></Select>
            </template>
          </ElTableColumn>
          <ElTableColumn prop="leftJoin" label="左连接" width="100px">
            <template #default="{ row }">
              <ElSwitch
                v-model="row['leftJoin']"
                :inline-prompt="true"
                active-text="是"
                inactive-text="否"
                :active-value="1"
                :inactive-value="0"
              ></ElSwitch>
            </template>
          </ElTableColumn>
          <ElTableColumn prop="action" label="操作" width="80px">
            <template #default="{ row }">
              <ElButton link type="danger" @click="handleDelete(row)">
                <Icon icon="delete"></Icon>
              </ElButton>
            </template>
          </ElTableColumn>
        </ElTable>
        <div style="margin: 10px">
          <ElButton link type="primary" @click="handleNewItem">
            <Icon icon="plus"></Icon>
            <span>添加一项</span>
          </ElButton>
        </div>
      </ElCard>
    </Drawer>
    <Dialog ref="menuDialogRef" @submit="handleMenuSubmit" :title="menuTitle">
      <Form ref="menuFormRef" :schemas="menuSchemas" label-width="100px">
        <template #pageId="{ formModel, schema }">
          <ApiSelect
            v-model="formModel[schema.field]"
            :request-api="microPageApi.list"
            :params="{ appId: rowRef.id }"
            value-name="id"
            label-name="pageName"
          ></ApiSelect>
        </template>
        <template #parentId="{ formModel, schema }">
          <ApiTreeSelect
            v-model="formModel[schema.field]"
            :request-api="menuApi.list"
            :callback="res => handleCallback(res)"
            filterable
            clearable
          ></ApiTreeSelect>
        </template>
      </Form>
    </Dialog>
    <Dialog ref="processDialogRef" @submit="handleProcessSubmit" title="流程部署">
      <Form ref="processFormRef" :schemas="processSchemas" label-width="100px"></Form>
    </Dialog>
  </div>
</template>

<script setup lang="tsx" name="MicroApp">
import { ref, watch } from "vue";
import { useRouter } from "vue-router";
import { ElCard, ElTable, ElTableColumn, ElButton, ElSwitch, ElMessage } from "element-plus";
import { Table, TableAction, useTable } from "@/components/Table";
import { Drawer, useDrawer } from "@/components/Drawer";
import { Dialog, useDialog } from "@/components/Dialog";
import { Form, useForm, ApiTreeSelect, ApiSelect, Select } from "@/components/Form";
import { ActionItem } from "@/components/Table/type";
import microPageApi from "@/views/micro/page/api";
import microEntityApi from "@/views/micro/entity/api";
import menuApi from "@/views/system/menu/api";
import microAppApi from "./api";
import { columns, basicSchemas, menuSchemas, processSchemas } from "./data";
import camundaApi from "@/views/micro/api/camunda.api";
import { Icon } from "@/components/Icon";
const tableRef = ref();
const drawerRef = ref();
const basicFormRef = ref();
const menuDialogRef = ref();
const menuFormRef = ref();
const processDialogRef = ref();
const processFormRef = ref();
const joinTableColumnMap = ref({});
const { getTableList } = useTable(tableRef);
const { open, close, openLoading } = useDrawer(drawerRef);
const basicForm = useForm(basicFormRef);
const menuDialog = useDialog(menuDialogRef);
const menuForm = useForm(menuFormRef);
const processDialog = useDialog(processDialogRef);
const processForm = useForm(processFormRef);
const entityList = ref([]);
const fieldList = ref([]);
const title = ref("");
const menuTitle = ref("");
const router = useRouter();
const rowRef = ref();
const openWatch = async () => {
  const formModel = await basicForm.getFields();
  entityList.value = (await microEntityApi.listAll({})) || [];
  watch(
    () => formModel.entityId,
    async id => {
      if (id) {
        fieldList.value = (await microEntityApi.listField({ id })) || [];
      } else {
        fieldList.value = [];
      }
    },
    {
      immediate: true
    }
  );
};
const handleCallback = (menus): Array<any> => {
  return filterMenu(menus);
};
const handleEntityModelChange = async id => {
  if (id) {
    if (!joinTableColumnMap.value[id]) {
      const res = (await microEntityApi.listField({ id })) || [];
      joinTableColumnMap.value[id] = res;
    }
  }
};
const filterMenu = (menus: Array<any>, disabled?: Boolean): Array<any> => {
  if (menus) {
    return menus.map(menu => {
      let _disabled = disabled || menu.menuType !== 0;
      return {
        value: menu.id,
        label: menu.menuName,
        disabled: _disabled,
        children: filterMenu(menu.children, _disabled)
      };
    });
  } else {
    return [];
  }
};
const handleAdd = async () => {
  title.value = "新增应用";
  await open(0);
  await basicForm.resetFields();
  modelList.value = [];
};
const modelList = ref([]);
const handleDelete = row => {
  for (let index = 0; index < modelList.value.length; index++) {
    if (modelList.value[index] === row) {
      modelList.value.splice(index, 1);
      break;
    }
  }
};
const handleNewItem = () => {
  modelList.value.push({ joinEntityId: null, joinEntityField: "", entityField: "", leftJoin: 0 });
};
const handleSubmit = async flag => {
  const fields = await basicForm.validateFields();
  for (const tm of modelList.value) {
    if (!tm.joinEntityId) {
      ElMessage.warning("请选择关联表");
      return;
    }
    if (!tm.joinEntityField) {
      ElMessage.warning("请选择关联字段");
      return;
    }
    if (!tm.entityField) {
      ElMessage.warning("请选择主表字段");
      return;
    }
  }
  fields.modelList = modelList.value;
  await openLoading(async () => {
    if (flag) {
      await microAppApi.edit(fields);
    } else {
      await microAppApi.add(fields);
    }
    close();
    await getTableList();
  });
};
const handleMenuSubmit = async flag => {
  const fields = await menuForm.validateFields();
  const res = {
    id: rowRef.value.id,
    menuType: 1,
    menuName: rowRef.value.appName,
    icon: fields.icon,
    parentId: fields.parentId,
    componentName: String(rowRef.value.id),
    componentType: 0,
    component: "/micro/render-page/index",
    path: "/micro/render/page",
    param: "pageId=" + fields.pageId,
    orderNum: fields.orderNum,
    hide: 0,
    affix: 0,
    keepAlive: 0
  };
  if (flag) {
    await menuApi.edit(res);
  } else {
    await menuApi.add(res);
  }
  await menuDialog.close();
};

const handleProcessSubmit = async () => {
  const fields = await processForm.validateFields();
  await camundaApi.deploy(fields);
  await processDialog.close();
};
const getActions = (row, id): Partial<ActionItem>[] => {
  return [
    {
      type: "primary",
      icon: "edit",
      onClick: async () => {
        title.value = "编辑应用";
        await open(1);
        await basicForm.updateFields(row);
        modelList.value = await microAppApi.getModelList({ id });
        for (const model of modelList.value) {
          await handleEntityModelChange(model.joinEntityId);
        }
      }
    },
    {
      type: "danger",
      popConfirm: {
        onConfirm: async () => {
          await microAppApi.remove(id);
          await getTableList();
        }
      },
      icon: "delete"
    },
    {
      type: "primary",
      icon: "spider",
      tooltip: "开发",
      onClick: async () => {
        await router.push("/micro/page/" + id);
      }
    },
    {
      type: "primary",
      icon: "menu",
      tooltip: "菜单",
      ifShow: row.pageType === 1,
      onClick: async () => {
        rowRef.value = row;
        const menu = await menuApi.query(row.id);
        if (menu) {
          menuTitle.value = "编辑菜单";
          await menuDialog.open(1);
          await menuForm.updateFields(menu);
        } else {
          menuTitle.value = "新增菜单";
          await menuDialog.open(0);
        }
      }
    },
    {
      type: "primary",
      icon: "position",
      tooltip: "部署",
      ifShow: row.pageType === 2,
      onClick: async () => {
        await processDialog.open();
        await processForm.updateFields({ appId: row.id, processName: row.appName });
      }
    }
  ];
};
</script>
